Rewrite the Windows Sandbox one-shot path onto an authenticated protocol (Phase 1)#577
Rewrite the Windows Sandbox one-shot path onto an authenticated protocol (Phase 1)#577MGudgin wants to merge 1 commit into
Conversation
b071f19 to
be48466
Compare
9d5d7e5 to
e3ccb02
Compare
60410fb to
e10515e
Compare
22cfc41 to
d140ea9
Compare
Comments heavily trimmed. |
d140ea9 to
daa4c4a
Compare
daa4c4a to
153e927
Compare
There was a problem hiding this comment.
Pull request overview
Reworks the Windows Sandbox one-shot execution path to use a new windows_sandbox_lifecycle crate with an authenticated host↔guest protocol, removing the legacy daemon-driven one-shot runner and aligning docs/tests with the “fresh VM per invocation” model.
Changes:
- Introduces
windows_sandbox_lifecycle(one-shotWindowsSandboxRunner+ VM lifecycle/policy/teardown primitives) and wiresmxc_enginedispatch to it. - Adds authenticated TCP channel setup (per-launch nonce + channel role) and a control-channel preamble; updates the guest agent accordingly (firewall + job-object cleanup).
- Updates Windows Sandbox docs and test runners/examples to reflect the new one-shot behavior and removes daemon pre-spawn assumptions.
Show a summary per file
| File | Description |
|---|---|
| tests/scripts/run_windows_sandbox_one_shot_tests.ps1 | Updates manual E2E runner for fresh-VM-per-test (but still has an elevated DISM preflight). |
| tests/scripts/README.md | Renames/clarifies Windows Sandbox script entry for one-shot suite. |
| tests/examples/10_windows_sandbox_network_isolated.json | Switches example command away from requiring host Python. |
| tests/examples/09_windows_sandbox_hello_world.json | Switches example command away from requiring host Python. |
| tests/configs/basic_windows_sandbox.json | Switches basic config away from requiring host Python. |
| src/testing/wxc_e2e_tests/tests/e2e_windows.rs | Removes daemon dependency from the Windows Sandbox E2E path. |
| src/core/wxc_common/src/models.rs | Marks WindowsSandboxConfig fields as legacy/ignored in one-shot. |
| src/core/mxc_engine/src/run.rs | Routes Windows Sandbox containment to windows_sandbox_lifecycle::WindowsSandboxRunner and warns on non-default legacy settings. |
| src/core/mxc_engine/Cargo.toml | Swaps Windows dependency from windows_sandbox_common to windows_sandbox_lifecycle. |
| src/Cargo.toml | Adds lifecycle crate to the workspace and removes the daemon member for this phase. |
| src/Cargo.lock | Updates dependency graph for new lifecycle crate and guest changes. |
| src/backends/windows_sandbox/lifecycle/Cargo.toml | Defines the new lifecycle crate and its dependencies. |
| src/backends/windows_sandbox/lifecycle/src/lib.rs | Exposes lifecycle modules and re-exports the one-shot runner on Windows. |
| src/backends/windows_sandbox/lifecycle/src/one_shot.rs | Implements the disposable one-shot ScriptRunner orchestration. |
| src/backends/windows_sandbox/lifecycle/src/policy.rs | Validates filesystem/network policy and maps to .wsb shares or rejects. |
| src/backends/windows_sandbox/lifecycle/src/vm.rs | Generates .wsb + bootstrap, launches Sandbox VM, captures ownership proof, and tears down. |
| src/backends/windows_sandbox/lifecycle/src/rendezvous.rs | Polls rendezvous file for guest ip:port and cleans up between runs. |
| src/backends/windows_sandbox/lifecycle/src/ipc_exec.rs | Adds framed exec protocol utilities (for upcoming state-aware daemon path). |
| src/backends/windows_sandbox/lifecycle/src/error.rs | Adds typed one-shot error mapping to ScriptResponse phases. |
| src/backends/windows_sandbox/lifecycle/src/control_plane/os.rs | Adds Win32 primitives for DACL, process identity, and named mutex locks. |
| src/backends/windows_sandbox/lifecycle/src/constants.rs | Centralizes daemon binary name constant (for Phase 2). |
| src/backends/windows_sandbox/lifecycle/src/bridge.rs | Implements authenticated 4-channel guest connection, preamble validation, and stdio/control relays. |
| src/backends/windows_sandbox/lifecycle/src/teardown.rs | Implements ownership-scoped teardown + marker-based crash recovery. |
| src/backends/windows_sandbox/guest/Cargo.toml | Adds Win32 windows dependency and tokio test-util for auth tests. |
| src/backends/windows_sandbox/guest/src/main.rs | Loads per-launch nonce and switches accepts/executor to authenticated protocol. |
| src/backends/windows_sandbox/guest/src/listener.rs | Accepts sockets by authenticated nonce + declared role (not accept order), with stall timeout handling. |
| src/backends/windows_sandbox/guest/src/executor.rs | Adds protocol preamble, avoids logging raw script text, improves process-tree cleanup and bounds stdio drain. |
| src/backends/windows_sandbox/guest/src/firewall.rs | Adds pre-authorization rule and tightens outbound rule to the established connection’s local port. |
| src/backends/windows_sandbox/guest/src/job.rs | Adds Job Object helper to terminate the full child process tree reliably. |
| src/backends/windows_sandbox/common/Cargo.toml | Adds tokio + getrandom for auth and async helpers. |
| src/backends/windows_sandbox/common/src/lib.rs | Exposes new auth module; removes the old one-shot runner export. |
| src/backends/windows_sandbox/common/src/auth.rs | Adds per-launch nonce + role handshake implementation. |
| src/backends/windows_sandbox/common/src/sandbox_protocol.rs | Adds control-channel preamble (magic + version) with validation. |
| src/backends/windows_sandbox/common/src/windows_sandbox_runner.rs | Deletes the legacy daemon-driven one-shot script runner. |
| docs/windows-sandbox/windows-sandbox.md | Updates high-level docs to reflect fresh-VM one-shot, auth protocol, and policy support/rejects. |
| docs/windows-sandbox/windows-sandbox-reference.md | Updates reference docs for new protocol/auth/preamble/teardown/markers model. |
| .github/copilot-instructions.md | Updates repo guidance to reflect new one-shot lifecycle implementation and test script name. |
Review details
Comments suppressed due to low confidence (1)
tests/scripts/run_windows_sandbox_one_shot_tests.ps1:52
- The script preflight uses
dism /get-featureinfo, which typically requires elevation and can reintroduce the non-elevated false-negative that this PR fixes (feature detection is now byWindowsSandbox.exepresence). Use a non-elevated file existence probe instead.
- Files reviewed: 37/38 changed files
- Comments generated: 1
- Review effort level: Low
501432b to
1124ea8
Compare
618e389 to
d2ae233
Compare
This PR rewrites the Windows Sandbox one-shot backend onto a fresh-VM lifecycle with an authenticated host-to-guest protocol and ownership-scoped teardown, and fixes non-elevated feature detection. Details * Adds `windows_sandbox_lifecycle` for policy validation, launch, rendezvous, execution, crash recovery, and guaranteed teardown of each disposable VM. * Authenticates every TCP channel with a per-launch nonce and channel role, and hardens guest process-tree cleanup and firewall isolation. * Routes the runner through `mxc_engine`, removes the host Python and warm-daemon dependencies, and warns only when non-default legacy daemon settings are ignored. * Rejects an existing Tokio runtime before host mutation or stdin-thread creation, avoiding a blocking thread leak on the error path. * Treats the state-aware daemon as optional in the Phase 1 SDK package; later stack phases build and require it. * Updates one-shot tests and documentation for the supported filesystem/network policy, protocol, security model, and debugging workflow. Tests * `cargo fmt --all -- --check` * `cargo check --workspace --all-targets` * `cargo clippy --workspace --all-targets -- -D warnings` * `cargo test --workspace --exclude wxc_host_prep` * `cargo check -p mxc_engine -p wxc --all-features` * `npm run build` (from `sdk`) Fixes #560 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c03d0923-5577-4c56-b2df-a314428f5164 Generated-with: claude-opus-4.8
d2ae233 to
053d70a
Compare
Phase 1 of the Windows Sandbox rewrite stack: rewrite the Windows Sandbox
one-shot backend onto a new
windows_sandbox_lifecyclecrate and anauthenticated host<->guest protocol, and fix the non-elevated feature-detection
false negative. The state-aware lifecycle + host daemon (Phase 2) and the SDK
(Phase 3) follow in stacked PRs.
Details
windows_sandbox_lifecyclecrate: the transient one-shotWindowsSandboxRunner(ScriptRunner) plus reusable VM lifecycle primitives(
vm,rendezvous,bridge,ipc_exec,policy,teardown,control_planehost-VM-lock/ownership + Win32osFFI).teardown on every exit path (normal/panic, Ctrl-C/shutdown handler,
next-run reconcile) -- no warm-VM reuse. The legacy
experimental.windows_sandbox.idleTimeoutMs/daemonPipeNamefields are stillparsed but ignored, with a stderr warning
(
WXC_WSB_ACK_ONESHOT_FRESH_VM=1silences the per-call notice).windows_sandbox_common::authadds a per-launch32-byte
Nonce+ 1-byteChannelRolehandshake on every TCP channel (boot +reconnect); the guest pairs accepted sockets by declared role, not accept
order, defeating cross-user accept-race hijack. Guest agent rewritten
(
listener/executor/job/firewall) onto the newsandbox_protocol+ auth.WindowsSandbox.exepresenceinstead of an elevated
dism /get-featureinfoquery, so a non-elevatedwxc-execno longer misreports "not enabled".windows_sandbox_common::windows_sandbox_runner; wxc one-shotdispatch constructs
WindowsSandboxRunner. The host daemon is dropped from theworkspace members for this phase (re-added with the state-aware lifecycle in
Phase 2); the dormant
control_planerecord/discovery functions arepubandcompile clean for Phase 2 to build on.
test_windows_sandboxand the renamedrun_windows_sandbox_one_shot_tests.ps1drop the daemon pre-spawn and exercisethe fresh-VM path. The full dual-mode backend-doc rewrites
(windows-sandbox.md/reference.md, schema.md, state-aware API) are deferred to
Phase 2, where they describe the end state; Phase 1 makes only minimal
P1-accurate touches to
copilot-instructions.md.Tests
cargo check --workspace --all-targets,cargo clippy --workspace --all-targets -- -D warnings, andcargo fmt --all -- --check: clean.cargo test: windows_sandbox_lifecycle 110, windows_sandbox_common 26, wxc 13,wxc_windows_sandbox_guest 8 -- all passed.
copy is
if exist-guarded) and that no source references the deleted runner.Fixes #560
Microsoft Reviewers: Open in CodeFlow